package www.wen.com.common.lib.base.module

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import www.wen.com.common.R
import www.wen.com.common.lib.data.entities.LoadingHelperType
import www.wen.com.common.lib.data.entities.LoadingHelperUiState
import www.wen.com.common.lib.data.entities.Result
import www.wen.com.common.lib.data.repository.AppDataManager
import www.wen.com.common.lib.extension.getString

/**
 * @author WEN
 * @Description:通用加载
 * @date 2021/9/15 18:17
 */
abstract class BaseAbsViewModel<T, K>(appDataManager: AppDataManager) : BaseApiViewModel(appDataManager) {

    private val _uiState = MutableLiveData<UiModel<List<K>>>()

    val uiState: LiveData<UiModel<List<K>>>
        get() = _uiState

    /**
     * 是否首次加载,加载成功后并且数据列表不为0的时候则设置为false
     */
    protected var mIsFirstLoading: Boolean = true

    /**
     * 页数
     */
    open var mPage = 0

    /**
     * 一次加载返回的数量
     */
    open val mLimit = 20

    /**
     * 是否每次都使用加载占位
     */
    open val mIsUseTitleLoading = false

    /**
     * 是否每次都使用错误占位
     */
    open val mIsUseTitleError = false

    protected var mIsRefresh = false

    var mJob: Job? = null

    fun requestGeneralListData(requiredParameter: Any, isRefresh: Boolean, action: (() -> Unit)? = null) {
        mIsRefresh = isRefresh
        mJob = viewModelScope.launch {
            showLoadingPlaceholder(isRefresh)

            if (isRefresh) mPage = 0

            val result = requestListData(requiredParameter)
            if (result is Result.Success<T>) {
                val lisData = dataConversion(result.data)
                if (mIsFirstLoading && lisData.isNotEmpty()) {
                    mPage++
                    mIsFirstLoading = false
                    loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.CONTENT)
                    emitArticleUiState(showSuccess = lisData, showEnd = mLimit > lisData.size)
                    action?.invoke()
                } else {
                    if (mIsFirstLoading) {
                        mPage++
                        loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.EMPTY)
                        emitArticleUiState(showSuccess = lisData, showEnd = mLimit > lisData.size,isRefresh = isRefresh)
                        action?.invoke()
                    } else {
                        ++mPage
                        loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.CONTENT)
                        emitArticleUiState(isRefresh = isRefresh, showSuccess = lisData, showEnd = mLimit > lisData.size)
                    }
                }
            } else if (result is Result.Error) {
                if (mIsFirstLoading) {
                    val message = result.exception.message ?: getString(R.string.network_anomaly)
                    val errorTip = if (message == getString(R.string.network_anomaly))
                        getString(R.string.network_anomaly)
                    else if (message == "服务器已被封禁") {
                        "服务器已被封禁"
                    } else {
                        result.exception.message ?: getString(R.string.error_data)
                    }
                    loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.ERROR, errorTip)
                } else {
                    if(mIsUseTitleError && !isRefresh){
                        val message = result.exception.message ?: getString(R.string.network_anomaly)
                        loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.ERROR, message)
                    }else{
                        emitArticleUiState(isRefresh = isRefresh, showError = result.exception.message ?: getString(R.string.network_anomaly))
                    }
                }
            }
        }
    }

    private fun showLoadingPlaceholder(isRefresh: Boolean) {
        if (mIsFirstLoading) {
            loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.LOADING)
        } else {
            if(mIsUseTitleLoading && !isRefresh){
                loadingUiHelper.value = LoadingHelperUiState(LoadingHelperType.LOADING)
            }else{
                emitArticleUiState(isRefresh = isRefresh, showLoading = true)
            }
        }
    }

    /**
     * 数据请求
     */
    abstract suspend fun requestListData(requiredParameter: Any): Result<T>

    /**
     * 返回的应该是一个对象，需要转换成list或者从对象中取出集合
     */
    abstract fun dataConversion(data: T): List<K>

    private fun emitArticleUiState(
            showLoading: Boolean = false,
            showError: String? = null,
            showSuccess: List<K>? = null,
            showEnd: Boolean = false,
            isRefresh: Boolean = false,
    ) {
        val uiModel = UiModel(showLoading, showError, showSuccess, showEnd, isRefresh)
        _uiState.value = uiModel
    }

    data class UiModel<T>(
            val showLoading: Boolean,
            val showError: String?,
            val showSuccess: T?,
            val showEnd: Boolean,
            val isRefresh: Boolean,
    )

}